package com.atguigu.demojuc.chap01;

//资源类
class Phone{
    public static synchronized void sendSms(){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发送短信");
    }

    public static synchronized void sendEmail(){
        System.out.println("发送邮件");
    }

    public void call(){
        System.out.println("打电话");
    }
}

/**
 * 讨论synchronized锁是谁的问题？ 8种情况下来讨论


 看下面这段儿代码，回答多线程的8个问题：

 1. 先访问短信，再访问邮件，先打印短信还是邮件
 短信
 邮件
 两个线程抢phone对象锁,由于A线程先启动具有优势，所以先打印‘短信’再打印'邮件'
 但实质上不分先后顺序的(谁先抢到锁不确定的)。两个线程相当于异步执行。


 2. 停4秒在短信方法内，先打印短信还是邮件
 短信
 邮件
 个线程抢phone对象锁,由于A线程先启动具有优势，所以先打印‘短信’再打印'邮件'
 即使A线程睡觉，睡觉持有锁不释放。

 3. 先访问短信，再访问hello方法，是先打短信还是hello
 hello
 短信
 A线程具有优势，但是抢锁休眠。B线程没有先天优势，但不需要抢锁不用睡觉，所以，先打印hello后打印短信

 4. 现在有两部手机，第一部发短信，第二部发邮件，先打印短信还是邮件
 邮件
 短信
 两部手机，两把锁。各抢各的锁，不用阻塞。
 由于A线程睡觉，B线程不睡觉。所以先打印邮件后打印短信。

 5. 两个静态同步方法，1部手机，先打印短信还是邮件
 短信
 邮件
 静态同步方法抢Phone类对象的锁。只有一把。
 Class clazz =  Phone.class
 Class clazz =  phone.getClass()
 A和B线程都抢同一把类对象锁，A有优势，即使睡觉也要执行任务后释放锁，B线程才能执行。

 6. 两个静态同步方法，2部手机，先打印短信还是邮件
 短信
 邮件
 静态同步方法抢类对象锁，与实体对象有几个无关。
 Class clazz =  Phone.class
 Class clazz =  phone.getClass()
 A和B线程都抢同一把类对象锁，A有优势，即使睡觉也要执行任务后释放锁，B线程才能执行。


 7. 1个静态同步方法，1个普通同步方法，1部手机，先打印短信还是邮件
 邮件
 短信
 A抢类对象锁(Phone.class)
 B抢实例对象锁(phone)
 两个线程两把锁，各用各的锁。不用相互阻塞。B不睡觉所以先执行。A睡觉所有后执行。

 8. 1个静态同步方法，1个普通同步方法，2部手机，先打印短信还是邮件
 邮件
 短信
 A抢类对象锁(Phone.class)
 B抢实例对象锁(phone2)
 两个线程抢两把锁，各用各的锁。不用相互阻塞。B不睡觉所以先执行。A睡觉所有后执行。


 ----------------------------------------------
 只有两种锁：

    Phone.class  类对象锁         static synchronized  静态同步方法
    phone,phone2  实例对象锁       synchronized 普通同步方法


 */
public class Lock8 {

    public static void main(String[] args) {
        Phone phone = new Phone();
        Phone phone2 = new Phone();

        new Thread(()->{
            phone.sendSms();
            //Phone.sendSms();
        },"A").start();

        new Thread(()->{
//            phone.sendEmail();
            //Phone.sendMail();
//            phone.call();
            phone2.sendEmail();
        },"B").start();
    }
}
